#include "tut6.h"

int sid;

void signalhandler(int sig)
{
    printf("Signal %d caught.\n", sig);

    if(0 > close(sid))
    {
	perror("Problem with close().");
	exit(1);
    }
    
    exit(0);
}

int main(int argc, char** argv)
{
    int pid;
    int duration;

    struct sockaddr_in saddr;
    struct sockaddr_in raddr;

    short port;
    short rport;

    struct hostent *hostinfo;

    if(argc != 4)
    {
	printf("tut 6 port rhostname rport\n");
	exit(1);
    }

    port = atoi(argv[1]);
    rport = atoi(argv[3]);

    if(0 > (hostinfo = gethostbyname(argv[2])))
    {
	perror("Problem with gethostbyname()");
	exit(1);
    }

    signal(SIGTERM, signalhandler);
    signal(SIGINT, signalhandler);

    //int socket(int domain, int type, int protocol)
    //domain: PF_INET, PF_INET6, PF_BLUETOOTH
    //type SOCK_DGRAM, SOCK_STREAM
    //protocol 
    if(0 > (sid = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)))
    {
	perror("Problem with perror()");
	exit(1);
    }

    //int bind(int sockfd, struct sockaddr* addr, 
    //socklen_t addrlen);
    memset((void *)&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(port);
    
    if(0 > bind(sid, (struct sockaddr *)&saddr, sizeof(saddr)))
    {
	perror("Problem with bind()");
	exit(1);
    }

    int val = 1;

    if(0 > setsockopt(sid, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)))
    {
	perror("Problem with setsockopt()");
	exit(1);
    }

   

    memset((void *)&raddr, 0, sizeof(raddr));
    raddr.sin_family = AF_INET;
    raddr.sin_port = htons(rport);
    memcpy(&raddr.sin_addr.s_addr, hostinfo->h_addr, hostinfo->h_length); 

    pid = fork();

    if(pid)
    {
	char *dummy = "Hello World";

	srandom(time(NULL) + getpid());

	while(1)
	{
	    //int sendto(int sockfd, const void *msg,
	    //size_t len, int flags, 
	    //const struct sockaddr *to,
	    //socklen_t tolen);
	    if(0 > sendto(sid, dummy, strlen(dummy), 0, 
                          (struct sockaddr* )&raddr, 
                          sizeof(raddr)))
	    {
		perror("Problem with send()");
		exit(1);
	    }

	    printf("Sending...\n");

	    sleep(random()%10);
	}
    }
    else
    {
	char item[4000];
	int length = sizeof(raddr);

	while(1)
	{
	    //int recvfrom(itn sockfd, void *item, size_t len,
	    //  flags, struct sockaddr* from socklen_t *from);
	    if(0 > recvfrom(sid, item, 4000, 0, 
			    (struct sockaddr *)&raddr, &length))
	    {
		perror("Problem recvfrom()");
		exit(1);
	    }

	    printf("Receiving: %s\n", item);
	}
    }
    
    
}
